/**
 * slkLni
 *   实现json,lua.Table,Lni3种格式的转换过程
 *   读取Lni和Table解析为json,
 *   JSON<->Lua.Table<->Lni
 */
 class slkLni {

    /**
     * 
     * @param [
     *    {
     *       name:"xx",
     *       fields:{
     *          "a":"b"    
     *      }
     *    }
     * ] data 
     */
    // data:[]
    constructor(data = []) {
        this.jsonRead(data);
    }

    init() {
        this.data = []
    }
    /**
     * json->
     */
    jsonRead(data = []) {
        if (Array.isArray(data)) {
            this.data = data;
        }
    }
    /**
     * Lni->json
     * w3x2lni的格式
     */
    LniRead(lniString) {
        this.data = [];
        let name = "";
        let fieldStatus = ""; //index,name,value
        let fieldName = "";
        let fieldValue = "";
        let fields = {};
        //去掉注释
        lniString = this.removeComments(lniString);
        lniString.forEach((s, i) => {
            if (i == lniString.length - 1) {
                //最后一个
                this.data.push({
                    name:name,
                    fields:fields
                });

            } else {
                switch (s) {
                    case "[":
                        //检查是否有数据
                        if(name){
                            this.data.push({
                                name:name,
                                fields:fields
                            });
                        }
                        //初始化
                        name = "";
                        fieldStatus = "index";
                        fieldName = "";
                        fieldValue = "";
                        fields = {};
                        break;
                    case "]":
                        fieldStatus = "name";
                        break;
                    case "=":
                        fieldStatus = "value";
                        break;
                    case `"`: case `'`:
                        //字符串属性
                        break;
                    case "\n":
                        if (fieldStatus == "value") {
                            if(fieldName){
                                //压入字段
                                fields[fieldName] = this.toNumber(fieldValue);
                            }
                            fieldStatus = "name";

                            fieldName = "";
                            fieldValue = "";
                        }
                        break;
                    default:
                        if (!this.isSpace(s)) {
                            if (fieldStatus == "index") {
                                name += s;
                            } else if (fieldStatus == "name") {
                                fieldName += s;
                            } else if (fieldStatus == "value") {
                                fieldValue += s;
                            }
                        }
                }
            }
        })
    }

    /**
     * Lua.Table->json
     * lua格式为
     * 多个大括号
     */
    luaRead(luaString) {
        this.data = [];
        let index = 0;
        let name = "";
        let fieldStatus = ""; //name,value
        let fieldValueString = false; //是否在字符串中 逗号
        let fieldName = "";
        let fieldValue = "";
        let fields = {};
        //去掉注释
        luaString = this.removeComments(luaString);
        luaString.forEach((s,i) => {
            switch (s) {
                case "{":
                    //初始化
                    name = "temp" + index;
                    fieldStatus = "name";
                    fieldName = "";
                    fieldValue = "";
                    fields = {};
                    break;
                case "}":
                    //压入数据
                    this.data.push({
                        name: name,
                        fields: fields
                    })
                    index = index + 1;
                    break;
                case "=":
                    fieldStatus = "value";
                    break;
                case ",":
                    //检查是否最后
                    if(!fieldValueString){
                        //压入字段
                        if(fieldName){
                            fields[fieldName] = this.toNumber(fieldValue);
                        }
                        fieldStatus = "name";
                        fieldName = "";
                        fieldValue = "";
                    }else{
                        fieldValue += s;
                    }
                    break;
                case `"`: case `'`:
                    //字符串属性
                    fieldValueString = !fieldValueString;
                    break;
                default:
                    if (!this.isSpace(s)) {
                        if (fieldStatus == "name") {
                            fieldName += s;
                        } else if (fieldStatus == "value") {
                            fieldValue += s;
                        }
                    }
            }
        })
    }

    /**
     * json->Lni
     */
    LniWrite() {
        //遍历josn生成lua->table
        let lniListString = "";
        this.data.forEach(item => {
            let name = item.name;
            let fields = item.fields;
            let lniString = this.lniTemplate();
            lniString = lniString.replace("$name$", name);
            let lniFieldsString = "";
            Object.keys(item.fields).forEach(fieldK => {
                let fieldV = item.fields[fieldK];
                lniFieldsString += "\n";
                lniFieldsString += this.isNumber(fieldV)
                    ? `${fieldK} = ${fieldV}`
                    : `${fieldK} = "${fieldV}"`
            })
            if (lniFieldsString) {
                lniString = lniString.replace("$fields$", lniFieldsString)
            }
            lniListString += lniString;
            lniListString += "\n";
        })
        return lniListString;
    }

    /**
     * json->Lua.table
     */
    luaWrite() {
        //遍历josn生成lua->table
        let luaTableString = "";
        this.data.forEach(item => {
            let name = item.name;
            let luaString = this.luaTemplate();
            luaString = luaString.replace("$name$", name);
            let luaFieldsString = "";
            Object.keys(item.fields).forEach(fieldK => {
                let fieldV = item.fields[fieldK];

                luaFieldsString += "\n";
                luaFieldsString += this.isNumber(fieldV)
                    ? `${fieldK} = ${fieldV}`
                    : `${fieldK} = "${fieldV}"` 
            })
            if (luaFieldsString) {
                luaString = luaString.replace("$fields$", luaFieldsString)
                luaTableString += luaString;
                luaTableString += "\n";
            }
        })
        return luaTableString;
    }

    luaTemplate() {
        return `
--$name$
{
    $fields$
}`
    }
    lniTemplate() {
        return `
[$name$]
$fields$`
    }
    /**
     * ->json
     */
    jsonWrite() {
        return this.data;
    }
    isSpace(s) {
        return s.match(/\s/);
    }
    isNumber(v) {
        let t = parseFloat(v);
        return typeof t == "number" && !isNaN(t);
    }
    toNumber(v){
        if(this.isNumber(v)){
            return v.includes(".") ? parseFloat(v) : parseInt(v) 
        }
        return v;
    }
    removeComments(content) {
        //检查是否包含注释
        //--开始后面的全部删除
        let result = [];
        if (content.includes("--")) {
            let conLines = content.split("\n");
            conLines.forEach(line => {
                if (line.includes("--")) {
                    if (line[0] == '-') {
                        //整行注释 忽略
                    } else if (line[0] != "-") {
                        //行尾注释  a=b, --xx
                        let temp = line.split("--");
                        result.push(temp[0]);
                    }
                } else {
                    result.push(line);
                }
            })
        }
        //字符串转数组
        return result.join("\n").split('');
    }
}